#include <stdio.h>
#include "easyShell.h"
#include <windows.h>

#define BAUD_RATE         CBR_115200
#define PORT_NAME         "COM3"
#define BUFFER_SIZE       256

HANDLE openSerialPort(const char *portName)
{
    HANDLE hSerial = CreateFileA(portName, GENERIC_READ | GENERIC_WRITE,
                               0, NULL, OPEN_EXISTING, 0, NULL);
    if (hSerial == INVALID_HANDLE_VALUE) {
        printf("Error opening serial port: %d\n", GetLastError());
        return INVALID_HANDLE_VALUE;
    }
    return hSerial;
}

BOOL setSerialPort(HANDLE hSerial) {
    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength = sizeof(DCB);

    // 获取当前串口设置并修改
    if (!GetCommState(hSerial, &dcbSerialParams)) {
        printf("Error getting current serial port settings: %d\n", GetLastError());
        CloseHandle(hSerial);
        return FALSE;
    }

    // 设置波特率和其他参数
    dcbSerialParams.BaudRate = BAUD_RATE;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;

    if (!SetCommState(hSerial, &dcbSerialParams)) {
        printf("Error setting serial port parameters: %d\n", GetLastError());
        CloseHandle(hSerial);
        return FALSE;
    }

    // 设置超时参数
    COMMTIMEOUTS timeouts;
    timeouts.ReadIntervalTimeout = MAXDWORD;
    timeouts.ReadTotalTimeoutMultiplier = 0;
    timeouts.ReadTotalTimeoutConstant = 0;
    timeouts.WriteTotalTimeoutMultiplier = 0;
    timeouts.WriteTotalTimeoutConstant = 0;

    if (!SetCommTimeouts(hSerial, &timeouts)) {
        printf("Error setting timeouts: %d\n", GetLastError());
        CloseHandle(hSerial);
        return FALSE;
    }

    return TRUE;
}

HANDLE hSerial;

void autoOpenPort(void)
{
    if(hSerial)
    {
        CloseHandle(hSerial);
    }
    hSerial = openSerialPort(PORT_NAME);
    if (hSerial != INVALID_HANDLE_VALUE)
    {
        setSerialPort(hSerial);
    }
}

void printSend(char* buf,uint16_t len)
{
    DWORD bytesWritten;
    if (!WriteFile(hSerial, buf, len, &bytesWritten, NULL))
    {
        printf("Error writing to serial port: %d\n", GetLastError());
    }
    autoOpenPort();
}

int led_main(int argc, char** argv)
{
    int i;

    printf("cmd:%s\n",argv[0]);

    for(i=1;i<argc;i++)
    {
        printf("param %d:%s\n",i,argv[i]);
    }
    return 0;
}

int main(void)
{
    char receiveBuffer[BUFFER_SIZE];
    DWORD bytesRead;

    shellCmdTypedef ledCmdInfo={
        .pName="led1",
    #if ES_CMD_BRIEF_ENABLE == 1
        .pBrief="simple demo",
    #endif
        .pFunc=led_main,
    };

    shellCmdTypedef led2CmdInfo={
        .pName="led2",
    #if ES_CMD_BRIEF_ENABLE == 1
        .pBrief="simple demo",
    #endif
        .pFunc=led_main,
    };


    autoOpenPort();

    easyShellInit(printSend);
    easyShellAddCmd(ledCmdInfo);
    easyShellAddCmd(led2CmdInfo);
    while(1)
    {
        bytesRead=0;
        if (!ReadFile(hSerial, &receiveBuffer, BUFFER_SIZE, &bytesRead, NULL))
        {
            printf("Error reading from serial port: %d\n", GetLastError());
        }
        else
        {
            if(bytesRead)
            {
                for(DWORD i=0;i<bytesRead;i++)
                {
                    easyShellReceiveData(receiveBuffer[i]);
                }
            }
        }
    }
}
